package com.minglv.mini.service.impl;

import com.dtflys.forest.http.ForestResponse;
import com.minglv.mini.apiclient.WxClient;
import com.minglv.mini.domain.*;
import com.minglv.mini.domain.dto.ApplyDto;
import com.minglv.mini.mapper.*;
import com.minglv.mini.service.IActivityService;
import com.minglv.mini.tools.*;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Service
//@DataSource(DataSourceType.SLAVE)
@Slf4j
public class ActivityServiceImpl implements IActivityService {

    @Autowired
    ActivityMapper activityMapper;

    @Resource
    UserFavoritesMapper userFavoritesMapper;

    @Resource
    UserInformationMapper userInformationMapper;

    @Resource
    UserMapper userMapper;

    @Resource
    ActivityApplyMapper activityApplyMapper;

    @Resource
    IntegralLogMapper integralLogMapper;

    @Resource
    ShareActivityMapper shareActivityMapper;

    @Resource
    WxTokenMapper wxTokenMapper;

    @Resource
    WxClient wxClient;

    @Override
//    @DataSource(DataSourceType.SLAVE)
    public List<Map> list(Integer active_status) {
        List<Map> list = activityMapper.getList(active_status);
        return list;
    }

    /**
     * 首页推荐活动列表
     *
     * @param isIndex
     * @return
     */
    @Override
//    @DataSource(DataSourceType.SLAVE)
    public List<Map> getIndexList(Integer isIndex) {
        return activityMapper.getIndexList(isIndex);
    }

    @Override
//    @DataSource(DataSourceType.SLAVE)
    public Map getActivityInfo(Integer active_id) {
        Map activityInfo = activityMapper.getActivityInfo(active_id);

        if (!CollectionUtils.isEmpty(activityInfo)) {

            Integer id = Integer.valueOf(activityInfo.get("id").toString());
            List<Map> activityApply = activityMapper.getActivityApply(id);
            if (!CollectionUtils.isEmpty(activityApply)) {
                activityApply = activityApply.stream().filter(map -> {
                    return Integer.valueOf(map.get("status").toString()) == 1 || Integer.valueOf(map.get("status").toString()) == 2;
                }).peek(map -> {
                    if (!ObjectUtils.isEmpty(map.get("forms"))) {
                        map.put("forms", JSONUtils.json2Map(map.get("forms").toString()));
                    }
                    if (!ObjectUtils.isEmpty(map.get("user_id"))) {
                        User user = userMapper.selectUserById(Long.valueOf(map.get("user_id").toString()));
                        Map userMap = new HashMap();
                        userMap.put("id", user.getId());
                        userMap.put("avatar", user.getAvatar());
                        map.put("user", userMap);
                    }
                }).collect(Collectors.toList());

            }
            activityInfo.put("apply",activityApply);
            if (!ObjectUtils.isEmpty(activityInfo.get("content"))) {
                //原有程序中有转换图片功能，现在暂时忽略
//                activityInfo.put("content",fixImgSrc(activityInfo.get("content").toString(),MiniProgramConstants.APP_URL));
            }

            Activity activity = activityMapper.selectActivityById(Long.valueOf(active_id));
            activity.setViews(ObjectUtils.isEmpty(activity.getViews()) ? 0L : activity.getViews() + 1L);
            activityMapper.updateActivity(activity);

        }

        return activityInfo;
    }


    public static String fixImgSrc(String content, String baseUrl) {
        // 匹配 <img> 标签并捕获 src 的值
        String regex = "<img[^>]*src=[\"']([^\"']*)[\"'][^>]*>";
        Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(content);
        StringBuffer sb = new StringBuffer();

        while (matcher.find()) {
            String url = matcher.group(1);

            // 判断是否是绝对地址 (http://, https://, 或 // 开头)
            if (!url.matches("^(https?:\\/\\/|\\/\\/).*")) {
                url = baseUrl.replaceAll("/+$", "") + "/" + url.replaceAll("^/+", "");
            }

            // 替换为新的 <img src="...">
            String replacement = "<img src=\"" + url + "\">";
            matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement));
        }
        matcher.appendTail(sb);

        return sb.toString();
    }

    @Override
//    @DataSource(DataSourceType.SLAVE)
    public Object iscollect(String token,Integer itemId,Integer type) {

        Long userId = JWTUtils.getUserid(token);

        if (ObjectUtils.isEmpty(userId)) {
            return null;
        }else{
            Map<String,Object> re = new HashMap<>();
            List<Map> userFavorites = activityMapper.getUserFavorites(type,itemId, userId);
            if (CollectionUtils.isEmpty(userFavorites)) {
                UserFavorites favorites = new UserFavorites();
                Long maxId = userFavoritesMapper.getMaxId();
                favorites.setStatus(1);
                favorites.setId(maxId + 1);
                favorites.setItemId(Long.valueOf(itemId));
                favorites.setUserId(userId);
                favorites.setType(1);
                userFavoritesMapper.insertUserFavorites(favorites);
                re.put("user_id",userId);
                re.put("id",favorites.getId());
                re.put("item_id",favorites.getItemId());
                re.put("type",favorites.getType());
                re.put("status",favorites.getStatus());
                re.put("create_at",new Date());
                re.put("update_at",new Date());
                return re;
            }
            re = userFavorites.get(0);
            return  re;
        }
    }

    @Override
//    @DataSource(DataSourceType.SLAVE)
    public Object collect(String token,Long id) {
        Long userId = JWTUtils.getUserid(token);
        if (ObjectUtils.isEmpty(userId)) {
            return null;
        }else{
            Map<String,Object> re = new HashMap<>();
            UserFavorites userFavorites = new UserFavorites();
            userFavorites.setUserId(userId);
            userFavorites.setItemId(id);
            userFavorites.setType(1);
            List<UserFavorites> userFavorites1 = userFavoritesMapper.selectUserFavoritesList(userFavorites);
            if (CollectionUtils.isEmpty(userFavorites1)) {
                UserFavorites uf = new UserFavorites();
                Long maxId = userFavoritesMapper.getMaxId();
                uf.setId(maxId + 1);
                uf.setStatus(1);
                uf.setUserId(userId);
                uf.setItemId(id);
                userFavoritesMapper.insertUserFavorites(uf);
                re.put("user_id",uf.getUserId());
                re.put("item_id",id);
                re.put("status",uf.getStatus());
                re.put("id",uf.getId());
                re.put("type",1);
                return re;
            }else{
                UserFavorites userFavorites2 = userFavorites1.get(0);
                userFavorites2.setStatus(userFavorites2.getStatus() == 1 ? 0 : 1);
                userFavoritesMapper.updateUserFavorites(userFavorites2);
                re.put("user_id",userFavorites2.getUserId());
                re.put("item_id",id);
                re.put("status",userFavorites2.getStatus());
                re.put("id",userFavorites2.getId());
                re.put("type",userFavorites2.getType());
                return re;
            }
        }
    }

    /**
     * 获取分享信息
     * @param token
     * @param id
     * @return
     */
    @Override
//    @DataSource(DataSourceType.SLAVE)
    public Object share(String token, Long id)  throws IOException {
        Long userId = JWTUtils.getUserid(token);
        Activity activity = activityMapper.selectActivityById(id);
        if (ObjectUtils.isEmpty(activity)) {
            Map reMap = new HashMap();
            reMap.put("status",201);
            reMap.put("msg","活动不存在");
            return MiniResult.success(reMap);
        }

        ShareActivity sa = new ShareActivity();
        sa.setUserId(userId);
        sa.setActiveId(id);
        List<ShareActivity> shareActivities = shareActivityMapper.selectShareActivityList(sa);
        if (CollectionUtils.isEmpty(shareActivities)) {
            String page = "pages/active/info";
            Map varMap = new HashMap();
            varMap.put("page",page);
            varMap.put("scene","id:" + id+",uid:" + userId);
            String access_token = this.getToken();
            ForestResponse<byte[]> getwxacodeunlimit = wxClient.getwxacodeunlimit(access_token, varMap);
            if (getwxacodeunlimit.statusOk()) {
                byte[] result = getwxacodeunlimit.getResult();
                String path = File.separator + "upload" + File.separator + "share" + File.separator + DateUtil.format(DateUtil.now(), "yyyyMMdd");
//                File folder  = new File(path);
//                if (!folder.exists()) {
//                    boolean r = folder.mkdir();
//                }
                Random random = new Random();
                Integer num = random.nextInt(900) + 100;
                String fileName = "img_" + UUID.randomUUID().toString() + num + ".jpg";
                FileOutputStream fos = null;
                try{
                    //存储到指定位置中
                    File absoluteFile = FileUploadUtils.getAbsoluteFile(FileUploadUtils.getDefaultBaseDir() + path, fileName);
                    fos = new FileOutputStream(absoluteFile);
                    fos.write(result);
                }finally {
                    IOUtils.close(fos);
                }
                Long maxId = shareActivityMapper.getMaxId();
                sa.setActiveId(maxId +1);
                sa.setUrl(path + File.separator + fileName);
                shareActivityMapper.insertShareActivity(sa);
            }
        } else {
            sa = shareActivities.get(0);
        }
        Map share = new HashMap();
        share.put("share_img", StringUtils.isNotEmpty(activity.getShareImg()) ? activity.getShareImg() : activity.getImgs());
        share.put("title",activity.getTitle().length() > 42 ? activity.getTitle().substring(0,14) + "..." : activity.getTitle());
        share.put("length",activity.getTitle().length());
        share.put("log",MiniProgramConstants.APP_URL + "/static/image/logo.png");
        share.put("share_code",MiniProgramConstants.APP_URL + sa.getUrl());
        share.put("user_id",sa.getUserId());
        share.put("url",sa.getUrl());
        share.put("active_id",id);
        share.put("id",sa.getId());
        activity.setShareTimes(ObjectUtils.isEmpty(activity.getShareTimes()) ? 0 : activity.getShareTimes() + 1);
        activityMapper.updateActivity(activity);
        User user = userMapper.selectUserById(userId);
        //加50积分
        //报名奖励推荐积分
        int share_jf = 50;
        user.setIntegral(user.getIntegral().add(new BigDecimal(share_jf)));
        log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>nickName:" + user.getNickname());
//        user.setNickname(null);
        userMapper.updateUser(user);
        IntegralLog log = new IntegralLog();
        Long maxId = integralLogMapper.getMaxId();
        log.setId(maxId + 1);
        log.setUserId(userId);
        log.setIntegral(new BigDecimal(share_jf));
        log.setRemark("分享活动奖励");
        log.setFromUser(0L);
        log.setActiveId(activity.getId());
        integralLogMapper.insertIntegralLog(log);
        return MiniResult.success(share);
    }

    @Override
    public List<Map> getListbyUserId(Integer status, Long userId) {
        return activityMapper.getListbyUserId(status,userId);
    }

    public String getToken(){
        String accessToken = "";
        WxToken wxToken = new WxToken();
        wxToken.setAppid(MiniProgramConstants.MINI_APPID);
        List<WxToken> wxTokens = wxTokenMapper.selectWxTokenList(wxToken);
        if (CollectionUtils.isEmpty(wxTokens)) {
            wxToken.setId(wxTokenMapper.getMaxId() + 1);
            wxTokenMapper.insertWxToken(wxToken);

        }else{
            accessToken = wxTokens.get(0).getAccessToken();
            wxToken = wxTokens.get(0);
        }

        if (DateUtil.now().compareTo(wxToken.getExpertTime()) > 0) {
            Map<String ,String> param = new HashMap<>();
            param.put("grant_type","client_credential");
            param.put("appid",MiniProgramConstants.MINI_APPID);
            param.put("secret",MiniProgramConstants.MINI_SECRET);

            ForestResponse<Map> mapForestResponse = wxClient.cgiBinToken(param);
            if (mapForestResponse.statusOk()) {
                Map result = mapForestResponse.getResult();
                wxToken.setAccessToken(result.get("access_token").toString());
                wxToken.setExpertTime(DateUtil.addSeconds(DateUtil.now(),Integer.valueOf(result.get("expires_in").toString())));
                accessToken = result.get("access_token").toString();
            }
            wxTokenMapper.updateWxToken(wxToken);
        }
        return  accessToken;
    }

    /**
     * 报名活动
     *
     * @param apply
     * @return
     */
    @Override
//    @DataSource(DataSourceType.SLAVE)
    public Object postApply(String token,ApplyDto apply) {
        Long userId = JWTUtils.getUserid(token);

        Activity activity = activityMapper.selectActivityById(apply.getId());
        if (ObjectUtils.isEmpty(activity)) {
            return new MiniResult(201,"活动不存在",new HashMap());
        }

        UserInformation ui = new UserInformation();
        ui.setUserId(userId);
        List<UserInformation> userInformations = userInformationMapper.selectUserInformationList(ui);
        if (CollectionUtils.isEmpty(userInformations)) {
            return new MiniResult(201,"请先完善用户信息!",new HashMap());
        }

        User user = userMapper.selectUserById(userId);
        if (user.getUserLevel() < activity.getUserLevel()) {
            return new MiniResult(201,"不在活动参与范围!",new HashMap());
        }

        if (user.getIntegral().compareTo(activity.getPrice()) == -1) {
            return new MiniResult(201,"积分不足,参与失败!",new HashMap());
        }

        ActivityApply aa = new ActivityApply();
        aa.setActiveId(apply.getId());
        aa.setUserId(userId);
        List<ActivityApply> activityApplies = activityApplyMapper.selectActivityApplyList(aa);
        if (!CollectionUtils.isEmpty(activityApplies)) {
            ActivityApply activityApply = activityApplies.get(0);
            if (activityApply.getStatus() == 4) {
                return new MiniResult(201,"报名被拒绝!",new HashMap());
            }else if(activityApply.getStatus() == 0 || activityApply.getStatus() == 1 || activityApply.getStatus() == 2){
                return  new MiniResult(201,"已经报名!",new HashMap());
            }
        }

        ActivityApply aca = new ActivityApply();
        aca.setUserId(userId);
        aca.setActiveId(apply.getId());
        aca.setStatus(0);
        if (apply.getShare_uid() > 0) {
            aca.setShareUid(apply.getShare_uid());
            User user1 = userMapper.selectUserById(apply.getShare_uid());
            //报名奖励推荐积分
            BigDecimal signJf = new BigDecimal(activity.getSignJf());
            user1.setIntegral(user1.getIntegral().add(signJf));
            user1.setUpdatedAt(new Date());
            userMapper.updateUser(user1);

            IntegralLog ll = new IntegralLog();
            Long maxId = integralLogMapper.getMaxId();
            ll.setId(maxId + 1);
            ll.setUserId(apply.getShare_uid());
            ll.setIntegral(new BigDecimal(activity.getSignJf()));
            ll.setRemark("推荐报名奖励");
            ll.setFromUser(userId);
            ll.setActiveId(apply.getId());
            integralLogMapper.insertIntegralLog(ll);
        }
        //扣分
        if(activity.getPrice().compareTo(BigDecimal.ZERO) > 0 ){
            user.setIntegral(user.getIntegral().subtract(activity.getPrice()));
            user.setUpdatedAt(new Date());
            userMapper.updateUser(user);
            IntegralLog ll = new IntegralLog();
            Long maxId = integralLogMapper.getMaxId();
            ll.setId(maxId + 1);
            ll.setUserId(userId);
            ll.setIntegral(activity.getPrice());
            ll.setRemark("报名活动消耗");
            ll.setType(2);
            ll.setFromUser(userId);
            ll.setActiveId(apply.getId());
            integralLogMapper.insertIntegralLog(ll);
        }

        Map formsMap = new HashMap();
        formsMap.put("realname",apply.getRealname());
        formsMap.put("phone",apply.getPhone());
        formsMap.put("company_name",apply.getCompany_name());
        formsMap.put("position",apply.getPosition());
        formsMap.put("email",apply.getEmail());
        String s = JSONUtils.bean2JsonString(formsMap);
        aca.setForms(s);

        Long maxId = activityApplyMapper.getMaxId();
        aca.setId(maxId + 1);
        int row = activityApplyMapper.insertActivityApply(aca);
        if(row > 0){
            return new MiniResult(200,"ok!",new HashMap());
        }else{
            return new MiniResult(201,"保存失败",new HashMap());
        }
    }

    /**
     * 查询【请填写功能名称】
     *
     * @param id 【请填写功能名称】主键
     * @return 【请填写功能名称】
     */
    @Override
    public Activity selectActivityById(Long id)
    {
        return activityMapper.selectActivityById(id);
    }

    /**
     * 查询【请填写功能名称】列表
     *
     * @param activity 【请填写功能名称】
     * @return 【请填写功能名称】
     */
    @Override
    public List<Activity> selectActivityList(Activity activity)
    {
        List<Activity> activities = activityMapper.selectActivityList(activity);
        return activities;
    }

    /**
     * 新增【请填写功能名称】
     *
     * @param activity 【请填写功能名称】
     * @return 结果
     */
    @Override
    public int insertActivity(Activity activity)
    {

        activity.setCreatedAt(new Date());
        activity.setUpdatedAt(new Date());
//        activity.setId(activityMapper.getMaxId() + 1);
        return activityMapper.insertActivity(activity);
    }

    /**
     * 修改【请填写功能名称】
     *
     * @param activity 【请填写功能名称】
     * @return 结果
     */
    @Override
    public int updateActivity(Activity activity)
    {
        return activityMapper.updateActivity(activity);
    }

    /**
     * 批量删除【请填写功能名称】
     *
     * @param ids 需要删除的【请填写功能名称】主键
     * @return 结果
     */
    @Override
    public int deleteActivityByIds(Long[] ids)
    {
        return activityMapper.deleteActivityByIds(ids);
    }

    /**
     * 删除【请填写功能名称】信息
     *
     * @param id 【请填写功能名称】主键
     * @return 结果
     */
    @Override
    public int deleteActivityById(Long id)
    {
        return activityMapper.deleteActivityById(id);
    }
}
